﻿using BaiTu.CachingEntity;
using BaiTu.CachingServices.Configuration;
using BaiTu.CachingServices.Coordinator.Algorithm;
using BaiTu.ICachingServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BaiTu.CachingServices.Coordinator.Wrappers
{
    public class CacheServersWrapper : ICacheProvider
    {
        private List<CacheServerInfo> configInfos;
        private List<string> serverAddressList = new List<string>();
        private List<CacheServerWrapper> cacheServerWrappers = new List<CacheServerWrapper>();
        KetamaNodeLocator locator = null;
        public CacheServersWrapper(List<CacheServerInfo> configInfos)
        {
            this.configInfos = configInfos;

            /*
            foreach (CacheServerInfo si in this.configInfos)
                if (si.ServerType == CacheServerType.HttpRuntime || si.ServerType == CacheServerType.InMemory)
                    throw new Exception("Hash algrith does not support " + si.ServerType.ToString());
            */

            foreach (CacheServerInfo si in this.configInfos)
                cacheServerWrappers.Add(new CacheServerWrapper(si));

            //初始化ip地址，给一致性hash算法使用
            this.configInfos.ForEach(t => serverAddressList.Add(string.Format("{0}:{1}", t.ServerAddress, t.ServerPort)));
            locator = new KetamaNodeLocator(this.serverAddressList, 160);
        }
        public void Put(string key, object value, CacheExpireType expireType, double increment)
        {
            string cacheServerAddress = GetCurrentIP(key);
            CacheServerWrapper executor = cacheServerWrappers.Single(t => t.FullServerAddress == cacheServerAddress);
            if (executor != null)
                executor.Put(key, value, expireType, increment);
        }

        public object Get(string key)
        {
            string cacheServerAddress = GetCurrentIP(key);
            CacheServerWrapper executor = cacheServerWrappers.Single(t => t.FullServerAddress == cacheServerAddress);
            if (executor != null)
                return executor.Get(key);
            return null;
        }

        public void Remove(string key)
        {
            string cacheServerAddress = GetCurrentIP(key);
            CacheServerWrapper executor = cacheServerWrappers.Single(t => t.FullServerAddress == cacheServerAddress);
            if (executor != null)
                executor.Remove(key);
        }



        private string GetCurrentIP(string key)
        {
            return locator.GetPrimary(key);
        }
    }
}
